package com.wwg.myapplication;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.view.View;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class AnimRipple extends Anim {
    // 动画状态变量
    private boolean isAnimationRunning = false;
    private boolean isAnimationCompleted = false;

    private static final int DROP_COUNT = 5;
    private static final float DROP_SIZE = 70f;
    private static final float RIPPLE_OPACITY = 0.7f; // 提高基础透明度
    private static final int[] RIPPLE_COLORS = {0xFFFFFFFF, 0xE6FFFFFF, 0xB3FFFFFF}; // 涟漪颜色渐变

    private final Paint dropPaint = new Paint();
    private final Paint ripplePaint = new Paint();
    private final View textView;
    private final Random random = new Random();

    private static class Drop {
        PointF position = new PointF();
        float size;
        float fallSpeed;
        float fallProgress;
        boolean hasSplash;
        float impactStrength;
        float targetY;
    }

    private static class Ripple {
        PointF center = new PointF();
        float radius = 0f;
        float maxRadius;
        float progress;
        boolean hasSecondary;
        boolean hasTertiary;

        // 优化的物理参数
        float velocity = 0f;
        float acceleration = -0.6f;    // 减小阻力
        float amplitude = 1.2f;        // 增大振幅
        float frequency = 1.8f;        // 降低频率
        float dampingFactor = 0.93f;   // 减小阻尼
        float elasticity = 0.4f;       // 增加弹性

        List<RippleLayer> layers = new ArrayList<>();
    }

    private static class RippleLayer {
        float radius;
        float opacity;
        float thickness; // 动态厚度
        float speed;
        float delay;
        float initialThickness; // 初始厚度
        float layerProgress; // 层进度

        RippleLayer(float speed, float delay, float thickness) {
            this.speed = speed;
            this.delay = delay;
            this.initialThickness = thickness;
            this.thickness = thickness;
            this.radius = 0f;
            this.opacity = 1.0f;
            this.layerProgress = 0f;
        }
    }

    private final List<Drop> drops = new ArrayList<>();
    private final List<Ripple> ripples = new ArrayList<>();
    private float globalCoverage = 0f;
    private float maxCoverageRadius = 0f;
    private float textAlpha = 0f;
    private boolean isCancelled = false;

    public AnimRipple(EnterAnimLayout view, View textView) {
        super(view, 15000); // 延长动画时长适配慢节奏
        this.textView = textView;

        dropPaint.setAntiAlias(true);
        dropPaint.setStyle(Paint.Style.FILL);
        dropPaint.setColor(0xAAFFFFFF);

        ripplePaint.setAntiAlias(true);
        ripplePaint.setStyle(Paint.Style.FILL);
    }

    public void cancelAnimation() {
        isCancelled = true;
        view.setmIsAnimaionRun(false);
    }

    @Override
    public void handleCanvas(Canvas canvas, float globalRate) {
        if (isCancelled) return;

        isAnimationRunning = true;
        w = view.getWidth();
        h = view.getHeight();
        if (w == 0 || h == 0) return;

        maxCoverageRadius = (float) Math.sqrt(w * w + h * h) / 2f;

        updateDrops(globalRate);
        drawDrops(canvas);

        updateRipples(globalRate);
        drawRipples(canvas);

        drawDynamicBackground(canvas, globalRate);
        updateTextAlpha(globalRate);

        if (globalRate < 1.0f) {
            view.invalidate();
        } else {
            // 原结束逻辑完全保留
            reset();
            view.setStartTime(System.currentTimeMillis()); // 重置开始时间
            view.invalidate(); // 触发下一轮动画
        }
    }

    private void drawDynamicBackground(Canvas canvas, float globalRate) {
        Paint bgPaint = new Paint();
        bgPaint.setShader(new RadialGradient(
                w / 2f, h / 2f, maxCoverageRadius * 0.8f,
                new int[]{0x33FFFFFF, 0x00FFFFFF},
                null,
                Shader.TileMode.CLAMP
        ));

        float bgAlpha = 0.3f * Math.min(1.0f, globalRate * 1.5f);
        int alpha = (int) (bgAlpha * 255);

        ripplePaint.setShader(null);
        ripplePaint.setColor(Color.argb(alpha, 255, 255, 255));
        canvas.drawRect(0, 0, w, h, ripplePaint);
    }

    private void updateDrops(float globalRate) {
        if (drops.isEmpty() && globalRate < 0.5f) {
            for (int i = 0; i < DROP_COUNT; i++) {
                addDrop();
            }
        }

        for (Drop drop : drops) {
            if (drop.fallProgress < 1.0f) {
                drop.fallProgress = Math.min(1.0f, drop.fallProgress + 0.004f * drop.fallSpeed);
                float progress = easeInQuart(drop.fallProgress);
                float startY = -DROP_SIZE * 2;
                drop.position.y = startY + (drop.targetY - startY) * progress;


                if (drop.fallProgress >= 1.0f && !drop.hasSplash) {
                    createAdvancedRipple(drop.position.x, drop.position.y, drop.impactStrength);
                    drop.hasSplash = true;
                }
            }
        }
    }

    private void addDrop() {
        Drop drop = new Drop();
        drop.position.x = w * (0.2f + 0.6f * random.nextFloat());
        drop.position.y = -DROP_SIZE * 2;
        drop.size = DROP_SIZE * (0.8f + 0.4f * random.nextFloat());
        drop.fallSpeed = 0.2f + 0.2f * random.nextFloat();
        drop.fallProgress = 0f;
        drop.hasSplash = false;
        drop.impactStrength = drop.size / DROP_SIZE;
        drop.targetY = h * (0.3f + 0.5f * random.nextFloat());
        drops.add(drop);
    }

    private void createAdvancedRipple(float x, float y, float impactStrength) {
        Ripple ripple = new Ripple();
        ripple.center.set(x, y);
        ripple.maxRadius = Math.min(w, h) * (0.15f + 0.2f * impactStrength);
        ripple.progress = 0f;
        ripple.velocity = 1.8f * impactStrength;
        ripple.amplitude = 0.8f + impactStrength * 0.5f;
        ripple.frequency = 1.2f + impactStrength * 0.6f;
        createRippleLayers(ripple, impactStrength);
        ripples.add(ripple);
    }

    private void createRippleLayers(Ripple ripple, float impactStrength) {
        ripple.layers.add(new RippleLayer(1.0f, 0f, 10.0f * impactStrength));
        ripple.layers.add(new RippleLayer(0.8f, 0.12f, 6.0f * impactStrength));
        ripple.layers.add(new RippleLayer(0.5f, 0.25f, 3.0f * impactStrength));
        if (impactStrength > 0.8f) {
            ripple.layers.add(new RippleLayer(0.3f, 0.4f, 2.0f * impactStrength));
        }
    }

    private void drawDrops(Canvas canvas) {
        for (Drop drop : drops) {
            if (drop.fallProgress < 1.0f) {
                float trailLength = drop.fallSpeed * 30f;
                for (int i = 0; i < 5; i++) {
                    float trailAlpha = (5 - i) * 0.1f;
                    float trailY = drop.position.y - i * trailLength * 0.2f;
                    float trailSize = drop.size * (1.0f - i * 0.1f);

                    Paint trailPaint = new Paint();
                    trailPaint.setAntiAlias(true);
                    trailPaint.setColor(Color.argb((int)(trailAlpha * 255), 255, 255, 255));
                    canvas.drawCircle(drop.position.x, trailY, trailSize * 0.6f, trailPaint);
                }

                Paint glowPaint = new Paint();
                glowPaint.setAntiAlias(true);
                glowPaint.setColor(0x55FFFFFF);
                glowPaint.setStyle(Paint.Style.FILL);
                canvas.drawCircle(drop.position.x, drop.position.y, drop.size * 1.5f, glowPaint);

                dropPaint.setShader(new RadialGradient(
                        drop.position.x, drop.position.y, drop.size,
                        new int[]{0xFFFFFFFF, 0xB3FFFFFF, 0x00FFFFFF},
                        new float[]{0f, 0.7f, 1f},
                        Shader.TileMode.CLAMP
                ));

                canvas.drawCircle(drop.position.x, drop.position.y, drop.size, dropPaint);

                Paint highlightPaint = new Paint();
                highlightPaint.setAntiAlias(true);
                highlightPaint.setColor(0xEEFFFFFF);
                canvas.drawCircle(
                        drop.position.x - drop.size * 0.3f,
                        drop.position.y - drop.size * 0.4f,
                        drop.size * 0.25f,
                        highlightPaint
                );
            }
        }
    }

    private void updateRipples(float globalRate) {
        for (int i = ripples.size() - 1; i >= 0; i--) {
            Ripple ripple = ripples.get(i);

            if (ripple.progress < 1.0f) {
                updateRipplePhysics(ripple);
                updateRippleLayers(ripple);
                createDelayedSecondaryRipples(ripple);
            }

            if (ripple.progress >= 1.0f) {
                ripples.remove(i);
            }
        }
    }

    private void updateRipplePhysics(Ripple ripple) {
        ripple.velocity += ripple.acceleration * 0.016f;
        ripple.velocity = Math.max(0.05f, ripple.velocity);
        float deltaProgress = ripple.velocity * 0.007f;
        ripple.progress = Math.min(1.0f, ripple.progress + deltaProgress);
        float easedProgress = easeOutElastic(ripple.progress);
        ripple.radius = ripple.maxRadius * easedProgress;
        ripple.amplitude *= ripple.dampingFactor;
    }

    private void updateRippleLayers(Ripple ripple) {
        for (RippleLayer layer : ripple.layers) {
            if (ripple.progress >= layer.delay) {
                layer.layerProgress = (ripple.progress - layer.delay) / (1.0f - layer.delay);
                layer.layerProgress = Math.min(1.0f, layer.layerProgress);
                float easedLayerProgress = easeOutQuad(layer.layerProgress);
                layer.radius = ripple.maxRadius * easedLayerProgress * layer.speed;
                layer.thickness = layer.initialThickness * (1.0f - (layer.layerProgress * 0.7f));
                layer.opacity = (1.0f - layer.layerProgress) * (0.5f + ripple.amplitude * 0.5f);
            }
        }
    }

    private void createDelayedSecondaryRipples(Ripple ripple) {
        if (ripple.progress >= 0.3f + (random.nextFloat() * 0.15f) && !ripple.hasSecondary) {
            float offsetX = (random.nextFloat() - 0.5f) * 60f * ripple.amplitude;
            float offsetY = (random.nextFloat() - 0.5f) * 60f * ripple.amplitude;
            createAdvancedRipple(
                    ripple.center.x + offsetX,
                    ripple.center.y + offsetY,
                    ripple.amplitude * (0.5f + random.nextFloat() * 0.3f)
            );
            ripple.hasSecondary = true;
        }

        if (ripple.progress >= 0.6f + (random.nextFloat() * 0.2f) && !ripple.hasTertiary && ripple.amplitude > 0.7f) {
            float offsetX = (random.nextFloat() - 0.5f) * 90f * ripple.amplitude;
            float offsetY = (random.nextFloat() - 0.5f) * 90f * ripple.amplitude;
            createAdvancedRipple(
                    ripple.center.x + offsetX,
                    ripple.center.y + offsetY,
                    ripple.amplitude * (0.2f + random.nextFloat() * 0.2f)
            );
            ripple.hasTertiary = true;
        }
    }

    private void drawRipples(Canvas canvas) {
        for (Ripple ripple : ripples) {
            if (ripple.progress > 0) {
                for (int layerIndex = 0; layerIndex < ripple.layers.size(); layerIndex++) {
                    RippleLayer layer = ripple.layers.get(layerIndex);
                    if (layer.radius > 0 && layer.opacity > 0.05f) {
                        drawRippleLayer(canvas, ripple, layer, layerIndex);
                    }
                }
                drawCenterWaves(canvas, ripple);
            }
        }
    }

    private void drawRippleLayer(Canvas canvas, Ripple ripple, RippleLayer layer, int layerIndex) {
        int baseAlpha = (int)(RIPPLE_OPACITY * 255 * layer.opacity);
        Paint ringPaint = new Paint();
        ringPaint.setAntiAlias(true);
        ringPaint.setStyle(Paint.Style.STROKE);
        ringPaint.setStrokeWidth(layer.thickness);
        ringPaint.setStrokeCap(Paint.Cap.ROUND);

        float waveIntensity = 1.0f - ripple.progress;
        float waveAmplitude = 4.0f * ripple.amplitude * waveIntensity * (1.0f - layerIndex * 0.2f);
        float waveOffset = (float) Math.sin(
                (ripple.progress * ripple.frequency * Math.PI * 2) + (layerIndex * 0.5f)
        ) * waveAmplitude;

        int alpha = (int)(baseAlpha * (1.0f - layerIndex * 0.25f));
        int[] colors = new int[RIPPLE_COLORS.length];
        for (int i = 0; i < colors.length; i++) {
            colors[i] = Color.argb(alpha,
                    Color.red(RIPPLE_COLORS[i]),
                    Color.green(RIPPLE_COLORS[i]),
                    Color.blue(RIPPLE_COLORS[i]));
        }

        RadialGradient ringGradient = new RadialGradient(
                ripple.center.x, ripple.center.y, layer.radius,
                colors,
                new float[]{0.9f, 0.95f, 1.0f},
                Shader.TileMode.CLAMP
        );
        ringPaint.setShader(ringGradient);

        canvas.drawCircle(ripple.center.x, ripple.center.y, layer.radius + waveOffset, ringPaint);

        // 修复layerProgress未定义问题，使用layer.layerProgress
        if (layerIndex == 0 && layer.layerProgress < 0.7f) {
            Paint glowPaint = new Paint();
            glowPaint.setAntiAlias(true);
            glowPaint.setStyle(Paint.Style.STROKE);
            glowPaint.setStrokeWidth(layer.thickness * 2.5f);
            glowPaint.setColor(Color.argb((int)(alpha * 0.2f), 255, 255, 255));
            canvas.drawCircle(ripple.center.x, ripple.center.y, layer.radius + waveOffset, glowPaint);
        }
    }

    private void drawCenterWaves(Canvas canvas, Ripple ripple) {
        if (ripple.progress < 0.6f) {
            float centerProgress = ripple.progress * 1.7f;
            int centerAlpha = (int)(120 * (1.0f - centerProgress) * ripple.amplitude);

            for (int i = 0; i < 3; i++) {
                float scale = 1.0f - i * 0.3f;
                float radius = 12f * centerProgress * ripple.amplitude * scale;
                float phase = (ripple.progress * 5f) + (i * 1.0f);
                float offset = (float) Math.sin(phase) * 2f * ripple.amplitude;

                Paint centerPaint = new Paint();
                centerPaint.setAntiAlias(true);
                centerPaint.setColor(Color.argb((int)(centerAlpha * (1.0f - i * 0.4f)), 255, 255, 255));
                canvas.drawCircle(
                        ripple.center.x + offset,
                        ripple.center.y + offset * 0.5f,
                        radius,
                        centerPaint
                );
            }
        }
    }

    private void updateTextAlpha(float globalRate) {
        if (globalRate < 0.5f) {
            textAlpha = 0f;
        } else if (globalRate < 0.8f) {
            textAlpha = (globalRate - 0.5f) / 0.3f;
        } else {
            textAlpha = 1.0f;
        }

        if (textView != null) {
            view.post(() -> textView.setAlpha(textAlpha));
        }
    }

    private float easeOutQuad(float t) {
        return t * (2 - t);
    }

    private float easeInQuart(float t) {
        return t * t;
    }

    private float easeOutElastic(float t) {
        if (t == 0) return 0;
        if (t == 1) return 1;

        float p = 0.4f;
        float s = p / 4;
        return (float)(Math.pow(2, -8 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1);
    }

    public void reset() {
        drops.clear();
        ripples.clear();
        globalCoverage = 0f;
        textAlpha = 0f;
        isCancelled = false;
        isAnimationRunning = false;
        isAnimationCompleted = false;

        if (textView != null) {
            textView.setAlpha(0f);
        }
    }

    public boolean isAnimationRunning() {
        return isAnimationRunning && !isCancelled;
    }

    public boolean isAnimationCompleted() {
        return isAnimationCompleted;
    }
}
